﻿// 开发者:micropu
// 公司:佛山远钧智慧科技有限公司

using Admin.NET.Application.LogService;
using Furion.Logging.Extensions;
using Furion.Schedule;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using LogLevel = Microsoft.Extensions.Logging.LogLevel;

namespace Admin.NET.Application.SysncService.PlatFormSync;

/// <summary>
/// 杨尘
/// </summary>
[SuppressSniffer]
public class YangChenSyncJob : IJob 
{
    private TcpClient client;
    private IWaitingClient<TcpClient> waitClient;  // 等待型客户端

    public async Task ExecuteAsync(JobExecutingContext context, CancellationToken stoppingToken)
    {
        var zJLog = App.GetService<ZJLog>();
        List<string> devicelists = new List<string>();
        devicelists.Add("Y2020075726008");
        devicelists.Add("YS20221128014");
        devicelists.Add("Y2020075723521");

        string serverAddress = "192.50.6.2"; // 服务器地址
        int serverPort = 9883; // 服务器端口
        string password = "123456"; // 密码
         
        // 创建TCP客户端
        client = new TcpClient();
        client.Setup(new TouchSocketConfig()
            .SetTcpDataHandlingAdapter(() => new MyFixedHeaderRequestInfo())
        );

        Console.WriteLine($"tcp://{serverAddress}:{serverPort}");
        client.Connect($"tcp://{serverAddress}:{serverPort}");
        waitClient = client.CreateWaitingClient(new WaitingOptions()
        {
            FilterFunc = response =>  //设置用于筛选的fun委托，当返回为true时，才会响应返回
            {
                return false;
            }
        });

        //if (!waitClient.CanSend)
        //{
        //    await zJLog.LogPlat(LogLevel.Information, LogType.Error, "连接住建失败", jobId_ClientSn, ProjectId, Tenantld, CreateOrgld, CreateOrgName);
        //    return;
        //}

        foreach (var device in devicelists)
        {
            string message = BuildHJ212Message(device, password);
            //// 将消息转换为字节数组
            //byte[] data = Encoding.ASCII.GetBytes(message + "\r\n");
            //var returnData = (await waitClient.SendThenResponseAsync(data));
            try
            {
                using (System.Net.Sockets.TcpClient client = new System.Net.Sockets.TcpClient(serverAddress, serverPort))
                {
                    NetworkStream stream = client.GetStream();

                    // 将消息转换为字节数组
                    byte[] data = Encoding.ASCII.GetBytes(message + "\r\n");

                    // 发送数据
                    stream.Write(data, 0, data.Length);
                    Console.WriteLine("数据已发送: " + message);

                    // 读取服务器响应
                    byte[] responseData = new byte[256];
                    int bytes = stream.Read(responseData, 0, responseData.Length);
                    string response = Encoding.ASCII.GetString(responseData, 0, bytes);
                    Console.WriteLine("服务器响应: " + response);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("连接失败: " + e.Message);
            }

        }

    }

    static string BuildHJ212Message(string deviceNumber, string password)
    {
        // string qn       = DateTime.Now.ToString("yyyyMMddHHmmssfff"); // 时间戳
        string qn = DateTime.Now.ToString("yyyyMMddHHmmss") + "000"; // 时间戳
        string dataTime = DateTime.Now.ToString("yyyyMMddHHmmss"); // 数据时间

        //TSP(全尘)实时值103-Rtd 21.6
        //PM2.5实时值925-Rtd=16.40
        //PM10实时值 107-Rtd=19.30
        //噪音 B03-Rtd=64.90

        Random random = new Random();

        // TSP (全尘) 实时值 103-Rtd
        double tspRtd = Math.Round(random.NextDouble() * 10+10, 2);  // 生成一个0到100之间的随机数，保留2位小数
        //Console.WriteLine($"TSP(全尘)实时值103-Rtd={tspRtd}");

        // PM2.5 实时值 925-Rtd
        double pm25Rtd = Math.Round(random.NextDouble() * 5+5, 2);  // 生成一个0到50之间的随机数，保留2位小数
        //Console.WriteLine($"PM2.5实时值925-Rtd={pm25Rtd}");

        // PM10 实时值 107-Rtd
        double pm10Rtd = Math.Round(random.NextDouble() * 5+10, 2);  // 生成一个0到50之间的随机数，保留2位小数
        //Console.WriteLine($"PM10实时值107-Rtd={pm10Rtd}");

        // 噪音 B03-Rtd
        double noiseRtd = Math.Round(random.NextDouble() * 30 + 30, 2);  // 生成一个30到130之间的随机数，保留2位小数
        //Console.WriteLine($"噪音B03-Rtd={noiseRtd}");

        // 构建 CP 部分
        string cp = $"DataTime={dataTime};" +
                    $"925-Rtd={pm25Rtd},925-Flag=N;" +
                    $"107-Rtd={pm10Rtd},107-Flag=N;" +
                    $"103-Rtd={tspRtd},103-Flag=N;" +
                    $"B03-Rtd={noiseRtd},B03-Flag=N;" +
                    "126-Rtd=35.70,126-Flag=N;" +
                    "128-Rtd=60.70,128-Flag=N;" +
                    "129-Rtd=0.00,129-Flag=N;" +
                    "130-Rtd=15,130-Flag=N;" +
                    "127-Rtd=0,127-Flag=N&&";

        // 组装消息主体
        //string messageContent = $"ST=22;CN=2011;QN={qn};PW={password};MN={deviceNumber};CP=&&{cp}&&";
        string messageContent = $"QN={qn};ST=22;CN=2011;PW=123456;MN={deviceNumber};Flag=5;CP=&&{cp}";


        // 计算消息的字节长度
        int length = messageContent.Length; // 加上“##”和消息长度字段及结束符"1B00"的字节数

        // 计算校验码
        string checksum = CalculateChecksum(messageContent);

        // 构建完整的消息，包含校验码和结束标志“1B00”
        //string message = $"##{length:D4}{messageContent}{checksum}1B00";
        string message = $"##{length:D4}{messageContent}{checksum}";

        return message;
    }

    public static string CalculateChecksum(string input)
    {
        ushort crc = 0xFFFF; // 初始值  

        foreach (char c in input)
        {
            crc ^= (byte)c; // 将字符转换为字节并与 CRC 进行异或  

            for (int i = 0; i < 8; i++)
            {
                // 检查最低位  
                if ((crc & 0x0001) == 1)
                {
                    crc = (ushort)((crc >> 1) ^ 0xA001); // 右移并与多项式进行异或  
                }
                else
                {
                    crc >>= 1; // 仅右移  
                }
            }
        }

        // 转换为四位十六进制字符串  
        return crc.ToString("X4").ToUpper(); // 返回四位十六进制字符串  
    }





}
